﻿// -----------------------------------------------------------------------
// <copyright file="CoverCacheManager.cs" company="EPAM Systems">
////Copyright (c) EPAM Systems. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

namespace Epam.PhotoGallery.Bussines.CacheManager
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Text;
	using Epam.PhotoGallery.Bussines.Configuration;
	using Microsoft.Practices.EnterpriseLibrary.Caching;
	using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
	using Epam.PhotoGallery.Interfaces.Managers;
	using System.Web;
	using System.Configuration;

	/// <summary>
	/// TODO: Update summary.
	/// </summary>
	public sealed class CoverCacheManager : IEpamGaleryCacheManager
	{
		#region Constants

		private const string Images = "Application.Images";

		#endregion

		#region private fields

		private IDictionary<string, CacheItem> images;

		private readonly ICacheManager cache = CacheFactory.GetCacheManager("Covers");
		private string currentTypeName;

		#endregion

		#region Constructor

		public CoverCacheManager(Type ownerType)
		{
			if (ownerType == null)
			{
				throw new ArgumentNullException("ownerType");
			}

			this.images = HttpContext.Current.Application[Images] as IDictionary<string, CacheItem>;

			if (this.images == null)
			{
				this.images = new Dictionary<string, CacheItem>();
				HttpContext.Current.Application[Images] = this.images;
			}

			this.currentTypeName = ownerType.FullName;
		}

		#endregion

		#region Public interface

		public void Add(string key, object value, int slide)
		{
			this.cache.Add(this.FormatKey(key), value, CacheItemPriority.High, null, new SlidingTime(TimeSpan.FromSeconds(slide)));
		}

		public bool TryAdd(string key, object value, int slide)
		{
			var result = false;
			CacheItem image;

			if (!this.images.TryGetValue(key, out image))
			{
				image = new CacheItem(DateTime.Now);
				this.images.Add(key, image);
			}

			var priorityOption = (CacheItemPrioritySection)ConfigurationManager.GetSection(CacheItemPrioritySection.Name);

			if (image.IsNeedToAddCache(priorityOption))
			{
				var cachePriority = (CacheItemPriority)image.GetCurrentCachePriority(priorityOption);

					this.cache.Add(this.FormatKey(key), value, cachePriority, null, new SlidingTime(TimeSpan.FromSeconds(priorityOption.StorageTime)));
					image.Clear();
					result = true;
			}

			return result;
		}

		public void Remove(string key)
		{
			this.cache.Remove(this.FormatKey(key));
		}

		public T GetItem<T>(string key) where T : class
		{
			T result = null;
			key = this.FormatKey(key);

			if (!string.IsNullOrEmpty(key))
			{
				result = this.cache.GetData(key) as T;
			}

			return result;
		}

		#endregion

		#region Internal implementation

		private string FormatKey(string key)
		{
			return string.Concat(this.currentTypeName, ".", key);
		}

		#endregion
	}
}
